package senders;
import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import sr.logger.Logger;

import main.Server;

import child.ChildServer;
import client.remote.ClientReceiver;

public class GameBroadcaster extends Thread {
	private Object lock = new Object();
	private BroadCaster masterBroadcaster;
	private Set<ClientReceiver> clients = new HashSet<ClientReceiver>();
	private boolean shutdown = false;
	private volatile int timeTillNextGame = 5000;
	private Server server;
	private Logger logger = Logger.getLogger(this.getClass());
	public GameBroadcaster(BroadCaster bc, Server server) {
		masterBroadcaster = bc;
		this.server = server;
		start();
	}

	public void addPlayer(ClientReceiver client) {
		synchronized (lock) {
			clients.add(client);
			try {
				client.informAboutGameStart(timeTillNextGame,logger.log("AddPlayer"));
			} catch (RemoteException e) {
				e.printStackTrace();
			}
		}
	}
	public void removePlayer(ClientReceiver client)
	{
		synchronized (lock)
		{
			clients.remove(client);
		}
	}
	public void shutdown() {
		shutdown = true;
	}

	@Override
	public void run() {
		while(!shutdown)
		{
			try {
				TimeUnit.MILLISECONDS.sleep(40);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		
			synchronized(lock)
			{
				if(clients.isEmpty())
					continue;
			}
			initiateGameStart();
		}
	}
	private void startGame() throws RemoteException
	{
		synchronized(lock)
		{
			
			ChildServer newServer = new ChildServer(new ArrayList<ClientReceiver>(clients),server);
			
			
			Long tick = logger.log("startGame");
			for(ClientReceiver client : clients)
			{
				
				try {
					client.startGame(newServer,tick);
				} catch (RemoteException e) {
					e.printStackTrace();
				}
			}
			clients.clear();
			
		}
	}
	private void initiateGameStart() {
		while (timeTillNextGame > 0) {
			try {
				TimeUnit.MILLISECONDS.sleep(20);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			timeTillNextGame -= 20;

			switch (timeTillNextGame) {
				case 3000: // three seconds
					masterBroadcaster
							.broadcastMessage("new game will start in 3 seconds");
					break;
				case 2000:
					masterBroadcaster.broadcastMessage("new game will start in 2 seconds");
					break;
				case 1000:
					masterBroadcaster.broadcastMessage("new game will start in 1 second");
					break;
				case 0:
				try {
					startGame();
				} catch (RemoteException e) {
					e.printStackTrace();
				}
			}
		}
		timeTillNextGame = 5000;
	}
}
